package it.ctr.game.toolkit;

import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

import com.mojang.mario.level.Level;

public class BrickBox
{
	public static final String IMAGE_PATH = "/it/ctr/game/toolkit/image/"; 
	public static final String SOUND_PATH = "/it/ctr/game/toolkit/sound/"; 
	
	public static final String JUMP = SOUND_PATH + "jump.wav";
	public static final String COIN = SOUND_PATH + "coin.wav";
	public static final String KICK = SOUND_PATH + "kick.wav";
	
	public static final int SAMPLE_BREAK_BLOCK = 0;
    public static final int SAMPLE_GET_COIN = 1;
    public static final int SAMPLE_MARIO_JUMP = 2;
    public static final int SAMPLE_MARIO_STOMP = 3;
    public static final int SAMPLE_MARIO_KICK = 4;
    public static final int SAMPLE_MARIO_POWER_UP = 5;
    public static final int SAMPLE_MARIO_POWER_DOWN = 6;
    public static final int SAMPLE_MARIO_DEATH = 7;
    public static final int SAMPLE_ITEM_SPROUT = 8;
    public static final int SAMPLE_CANNON_FIRE = 9;
    public static final int SAMPLE_SHELL_BUMP = 10;
    public static final int SAMPLE_LEVEL_EXIT = 11;
    public static final int SAMPLE_MARIO_1UP = 12;
    public static final int SAMPLE_MARIO_FIREBALL = 13;

    public static Image[][] levelBrick;
    public static Image[][] mario;
    public static Image[][] smallMario;
    public static Image[][] fireMario;
    public static Image[][] enemies;
    public static Image[][] items;
    public static Image[][] level;
    public static Image[][] particles;
    public static Image[][] font;
    public static Image[][] bg;
    public static Image[][] map;
    public static Image[][] endScene;
    public static Image[][] gameOver;
    public static Image logo;
    public static Image title;
    
    private static Sequence[] songs = new Sequence[10];
    private static Sequencer sequencer;


    public static void init(GraphicsConfiguration gc)
    {
        try
        {
        	levelBrick = cutImage(gc, IMAGE_PATH + "BrickViewer.png", Level.BLOCK_SIZE, 48);
            mario = cutImage(gc, IMAGE_PATH + "personaggio.png", 96, 96);
            smallMario = cutImage(gc, IMAGE_PATH + "personaggio.png", 96, 96);
            fireMario = cutImage(gc, IMAGE_PATH + "personaggio.png", 96, 96);
            enemies = cutImage(gc, IMAGE_PATH + "enemysheet.png", 16, 32);
            items = cutImage(gc, IMAGE_PATH + "itemsheet.png", 16, 16);
            level = cutImage(gc, IMAGE_PATH + "mapsheet.png", 16, 16);
            map = cutImage(gc, IMAGE_PATH + "worldmap.png", 16, 16);
            particles = cutImage(gc, IMAGE_PATH + "particlesheet.png", 8, 8);
            bg = cutImage(gc, IMAGE_PATH + "bgsheet.png", 32, 32);
            logo = getImage(gc, IMAGE_PATH + "logo.gif");
            title = getImage(gc, IMAGE_PATH + "title.png");
            font = cutImage(gc, IMAGE_PATH + "font.gif", 8, 8);
            endScene = cutImage(gc, IMAGE_PATH + "endscene.gif", 96, 96);
            gameOver = cutImage(gc, IMAGE_PATH + "gameovergost.gif", 96, 64);

//            if (sound != null)
//            {
//                samples[SAMPLE_BREAK_BLOCK] = sound.loadSample("/snd/breakblock.wav");
//                samples[SAMPLE_GET_COIN] = sound.loadSample("/snd/coin.wav");
//                samples[SAMPLE_MARIO_JUMP] = sound.loadSample("/snd/jump.wav");
//                samples[SAMPLE_MARIO_STOMP] = sound.loadSample("/snd/stomp.wav");
//                samples[SAMPLE_MARIO_KICK] = sound.loadSample("/snd/kick.wav");
//                samples[SAMPLE_MARIO_POWER_UP] = sound.loadSample("/snd/powerup.wav");
//                samples[SAMPLE_MARIO_POWER_DOWN] = sound.loadSample("/snd/powerdown.wav");
//                samples[SAMPLE_MARIO_DEATH] = sound.loadSample("/snd/death.wav");
//                samples[SAMPLE_ITEM_SPROUT] = sound.loadSample("/snd/sprout.wav");
//                samples[SAMPLE_CANNON_FIRE] = sound.loadSample("/snd/cannon.wav");
//                samples[SAMPLE_SHELL_BUMP] = sound.loadSample("/snd/bump.wav");
//                samples[SAMPLE_LEVEL_EXIT] = sound.loadSample("/snd/exit.wav");
//                samples[SAMPLE_MARIO_1UP] = sound.loadSample("/snd/1-up.wav");
//                samples[SAMPLE_MARIO_FIREBALL] = sound.loadSample("/snd/fireball.wav");
//            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        try
        {
            sequencer = MidiSystem.getSequencer();
            sequencer.open();
            songs[0] = MidiSystem.getSequence(BrickBox.class.getResourceAsStream("/mus/smb3map1.mid"));
            songs[1] = MidiSystem.getSequence(BrickBox.class.getResourceAsStream("/mus/smwovr1.mid"));
            songs[2] = MidiSystem.getSequence(BrickBox.class.getResourceAsStream("/mus/smb3undr.mid"));
            songs[3] = MidiSystem.getSequence(BrickBox.class.getResourceAsStream("/mus/smwfortress.mid"));
            songs[4] = MidiSystem.getSequence(BrickBox.class.getResourceAsStream("/mus/smwtitle.mid"));
        }
        catch (Exception e)
        {
            sequencer = null;
            e.printStackTrace();
        }
    }

    private static Image getImage(GraphicsConfiguration gc, String imageName) throws IOException
    {
        BufferedImage source = ImageIO.read(BrickBox.class.getResourceAsStream(imageName));
        Image image = gc.createCompatibleImage(source.getWidth(), source.getHeight(), Transparency.BITMASK);
        Graphics2D g = (Graphics2D) image.getGraphics();
        g.setComposite(AlphaComposite.Src);
        g.drawImage(source, 0, 0, null);
        g.dispose();
        return image;
    }

    private static Image[][] cutImage(GraphicsConfiguration gc, String imageName, int xSize, int ySize) throws IOException
    {
        Image source = getImage(gc, imageName);
        Image[][] images = new Image[source.getWidth(null) / xSize][source.getHeight(null) / ySize];
        for (int x = 0; x < source.getWidth(null) / xSize; x++)
        {
            for (int y = 0; y < source.getHeight(null) / ySize; y++)
            {
                Image image = gc.createCompatibleImage(xSize, ySize, Transparency.BITMASK);
                Graphics2D g = (Graphics2D) image.getGraphics();
                g.setComposite(AlphaComposite.Src);
                g.drawImage(source, -x * xSize, -y * ySize, null);
                g.dispose();
                images[x][y] = image;
            }
        }

        return images;
    }

    public static void drawString(Graphics g, String text, int x, int y, int c)
    {
        try {
			char[] ch = text.toCharArray();
			for (int i = 0; i < ch.length; i++)
			{
			    g.drawImage(BrickBox.font[ch[i] - 32][c], x + i * 8, y, null);
			}
		} catch (Exception e) {
			// TODO capire perche va in eccezione
			e.printStackTrace();
		}
    }
    
    public static void startMusic(int song)
    {
        stopMusic();
        if (sequencer != null)
        {
            try
            {
                sequencer.open();
                sequencer.setSequence((Sequence)null);
                sequencer.setSequence(songs[song]);
                sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
                sequencer.start();
            }
            catch (Exception e)
            {
            }
        }
    }

    public static void stopMusic()
    {
        if (sequencer != null)
        {
            try
            {
                sequencer.stop();
                sequencer.close();
            }
            catch (Exception e)
            {
            }
        }
    }
    
    public static void playSound(String strSound) {
        try {
			Clip clickClip = AudioSystem.getClip();
			URL clipURL = BrickBox.class.getResource(strSound);
			AudioInputStream ais = AudioSystem.getAudioInputStream(clipURL);
			clickClip.open(ais);
			clickClip.start();
		} catch (Exception e) {
			e.printStackTrace();
		}	
    }
}